﻿using Cofe.Core.Property;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cofe.Core.Utils;

namespace Cofe.Core.Property
{
    public static class IPropertyProviderExtension
    {
        public static Task SetPropertyAsync(this IPropertyProvider propertyProvider, object property, object value)
        {
            return propertyProvider.SetPropertyAsync(PropertyPair.FromValue(property, value));
        }

        public static void SetProperty(this IPropertyProvider propertyProvider, object property, object value)
        {
            AsyncUtils.RunSync(() => propertyProvider.SetPropertyAsync(property, value));
        }

        public static Task CachePropertyAsync(this IPropertyCache propertyCache, object property, object value)
        {
            return propertyCache.CachePropertyAsync(PropertyPair.FromValue(property, value));
        }

        public static void CacheProperty(this IPropertyCache propertyCache, object property, object value)
        {
            AsyncUtils.RunSync(() => propertyCache.CachePropertyAsync(property, value));
        }

        public static IPropertyDefinitions[] GetSupportedDefinitions(
            this IPropertyProvider[] propertyProviders)
        {
            return propertyProviders.SelectMany((pp) => pp.SupportedDefinitions).Distinct().ToArray();
        }

        public static PropertyPair GetOneProperty(this IPropertyProvider propertyProvider, object property)
        {
            return propertyProvider.GetPropertyAsync(property).Result.Find(property);
        }


        public static T GetOneProperty<T>(this IPropertyProvider propertyProvider, object property)
        {
            return propertyProvider.GetOneProperty(property).ValueAs<T>();
        }

        public static async Task<PropertyPair> GetOnePropertyAsync(this IPropertyProvider propertyProvider, object property)
        {
            return (await propertyProvider.GetPropertyAsync(property)).Find(property);
        }

        public static async Task<T> GetOnePropertyAsync<T>(this IPropertyProvider propertyProvider, object property)
        {
            return (await propertyProvider.GetOnePropertyAsync(property)).ValueAs<T>();
        }

        public static IEnumerable<object> GetSupportedProperties(
           this IPropertyProvider[] propertyProviders)
        {
            return propertyProviders.SelectMany(pp => pp.SupportedDefinitions)
                .SelectMany(sd => sd.GetSupportedProperties())
                .Distinct().ToArray();
        }
    }
}
